package cn.swust.designpatternlearningplatform.service.impl;

import cn.swust.designpatternlearningplatform.common.Result.PageInfo;
import cn.swust.designpatternlearningplatform.common.utils.OrikaMapperUtil;
import cn.swust.designpatternlearningplatform.dao.TopicDao;
import cn.swust.designpatternlearningplatform.dao.TopicKnowledgePointDao;
import cn.swust.designpatternlearningplatform.dao.TopicOptionDao;
import cn.swust.designpatternlearningplatform.dao.TopicUpdateDao;
import cn.swust.designpatternlearningplatform.domain.bo.StudentTopicTypeBo;
import cn.swust.designpatternlearningplatform.domain.dto.KnowledgePointDto;
import cn.swust.designpatternlearningplatform.domain.dto.TopicCollectDto;
import cn.swust.designpatternlearningplatform.domain.dto.TopicOptionDto;
import cn.swust.designpatternlearningplatform.domain.entity.*;
import cn.swust.designpatternlearningplatform.domain.enums.TopicUpdateTypeEnum;
import cn.swust.designpatternlearningplatform.service.TopicCollectService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.sql.Timestamp;
import java.time.Instant;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class TopicCollectServiceImpl implements TopicCollectService {
    @Resource
    private TopicUpdateDao topicUpdateDao;
    @Resource
    private TopicDao topicDao;
    @Resource
    private TopicKnowledgePointDao topicKnowledgePointDao;
    @Resource
    private TopicOptionDao topicOptionDao;

    @Override
    public PageInfo<TopicCollectDto> getCollectQuestionByStudentNumber(StudentTopicTypeBo studentTopicTypeBo) {
        TopicUpdate topicUpdate = new TopicUpdate();
        BeanUtils.copyProperties(studentTopicTypeBo, topicUpdate, "topicId");
        Integer current = studentTopicTypeBo.getCurrent();
        Integer size = studentTopicTypeBo.getSize();
        Integer total = topicUpdateDao.selectTopicUpdateByStudentTotal(topicUpdate);
        List<TopicUpdate> topicUpdates = topicUpdateDao.
                selectTopicUpdateByStudent(topicUpdate, (current - 1) * size, size);
        //1.批量查询题目信息
        List<Integer> topicIds = topicUpdates
                .stream()
                .map(TopicUpdate::getTopicId).collect(Collectors.toList());
        Map<Integer, Topic> topicMap = topicDao.selectTopicsByIds(topicIds)
                .stream()
                .collect(Collectors.toMap(Topic::getTopicId, i -> i));
        //2.查看屏蔽状态
        topicUpdate.setUpdateType(TopicUpdateTypeEnum.SHIELD.getTypeName());
        Set<Integer> isShield = new HashSet<>(topicUpdateDao.selectAllByTopicType(topicUpdate));
        if (topicIds.isEmpty()) {
            return new PageInfo<>(total, current, size, new ArrayList<>());
        }
        //3.查询知识点
        List<TopicKnowledgeCorrelation> points = new ArrayList<>(topicKnowledgePointDao.selectByTopicIds(topicIds));
        //4.查询选项
        List<TopicOption> topicOptions = topicOptionDao.getByTopicIds(new HashSet<>(topicIds));
        List<TopicOptionDto> topicOptionDtos = OrikaMapperUtil.INSTANCE.mapAsList(TopicOptionDto.class, topicOptions);
        Map<Integer, List<TopicOptionDto>> topicOptionDtoMap = topicOptionDtos.stream()
                .collect(Collectors.groupingBy(TopicOptionDto::getTopicId));
        //5.封装收藏题对象
        List<TopicCollectDto> topicShieldDtos = topicUpdates
                .stream().filter(Objects::nonNull).map(i -> {
                    TopicCollectDto topicCollectDto = new TopicCollectDto();
                    //5.1收藏信息
                    BeanUtils.copyProperties(i, topicCollectDto);
                    //5.2题目信息
                    Topic topic = topicMap.get(i.getTopicId());
                    if (topic != null) {
                        BeanUtils.copyProperties(topic, topicCollectDto);
                        //5.3是否收藏
                        topicCollectDto.setIsShield(isShield.contains(i.getTopicId()));
                        //5.4题目难度
                        topicCollectDto.setTopicDifficulty(topic.getTopicDifficulty());
                        //5.5设置题目知识点信息
                        topicCollectDto.setPoints(new ArrayList<>());
                        points.forEach(j -> {
                            if (i.getTopicId().equals(j.getTopicId())) {
                                KnowledgePointDto knowledgePointDto = new KnowledgePointDto();
                                BeanUtils.copyProperties(j, knowledgePointDto);
                                topicCollectDto.getPoints().add(knowledgePointDto);
                            }
                        });
                        //5.6设置题目选项
                        topicCollectDto.setTopicOptionDtos(topicOptionDtoMap.get(i.getTopicId()));
                    }
                    return topicCollectDto;
                }).collect(Collectors.toList());

        return new PageInfo<>(total, current, size, topicShieldDtos);
    }

    @Override
    public void deleteCollectTopic(String studentNumber, List<Integer> topicIds) {
        TopicUpdate topicUpdate = new TopicUpdate();
        topicUpdate.setStudentNumber(studentNumber);
        topicUpdate.setUpdateType(TopicUpdateTypeEnum.COLLECT.getTypeName());
        topicIds.forEach(i -> {
            topicUpdate.setTopicId(i);
            topicUpdateDao.deleteTopicUpdate(topicUpdate);
        });
    }

    /**
     * 批量添加收藏
     *
     * @param studentNumber
     * @param topicIds
     * @return void
     * @author Tang
     * @date 2023/7/10 13:54
     **/
    @Override
    public void addCollectTopic(String studentNumber, List<Integer> topicIds) {
        Map<Integer, String> collect = topicDao.selectTopicsByIds(topicIds)
                .stream()
                .collect(Collectors.toMap(Topic::getTopicId, Topic::getTopicType));
        for (Integer id : topicIds) {
            TopicUpdate topicUpdate = new TopicUpdate();
            topicUpdate.setStudentNumber(studentNumber);
            topicUpdate.setTopicId(id);
            topicUpdate.setUpdateType(TopicUpdateTypeEnum.COLLECT.getTypeName());
            topicUpdate.setUpdateTime(Timestamp.from(Instant.now()));
            topicUpdate.setTopicType(collect.get(id));
            //已经收藏
            if (topicUpdateDao.selectTopicUpdate(topicUpdate) != null) {
                continue;
            }
            //未收藏
            topicUpdateDao.insertTopicUpdate(topicUpdate);
        }
    }

    @Override
    public List<TopicUpdate> getCollectsByStuNumAndTopicIds(String studentNumber, Collection<Integer> topicIds, String typeName) {

        return topicUpdateDao.getCollectsByStuNumAndTopicIds(studentNumber, topicIds, typeName);
    }
}

